"""
文档处理模块
负责Word文档的格式修改和保存
"""

import os
from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from typing import Optional, Dict

class DocumentProcessor:
    def __init__(self):
        self.color_map = {
            "黑色": RGBColor(0, 0, 0),
            "红色": RGBColor(255, 0, 0),
            "蓝色": RGBColor(0, 0, 255),
            "绿色": RGBColor(0, 255, 0)
        }

    def apply_format(self, file_path: str, template: Dict,
                   output_path: Optional[str] = None):
        """
        应用格式到文档
        :param file_path: 输入文件路径
        :param template: 样式模板
        :param output_path: 输出文件路径(可选)
        :return: None
        """
        doc = Document(file_path)

        # 处理标题
        if "title" in template:
            self._format_paragraphs(doc.paragraphs, template["title"], is_title=True)

        # 处理正文
        for para in doc.paragraphs:
            style_name = para.style.name.lower()

            if "heading 1" in style_name and "heading1" in template:
                self._format_paragraph(para, template["heading1"])
            elif "heading 2" in style_name and "heading2" in template:
                self._format_paragraph(para, template["heading2"])
            elif "heading 3" in style_name and "heading3" in template:
                self._format_paragraph(para, template["heading3"])
            elif "heading 4" in style_name and "heading4" in template:
                self._format_paragraph(para, template["heading4"])
            elif "heading" not in style_name and "body" in template:
                self._format_paragraph(para, template["body"])

        # 处理表格
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    for para in cell.paragraphs:
                        if "body" in template:
                            self._format_paragraph(para, template["body"])

        # 保存文档
        save_path = output_path if output_path else file_path
        doc.save(save_path)

    def preview_format(self, file_path: str, template: Dict) -> str:
        """
        预览格式修改效果
        :param file_path: 文件路径
        :param template: 样式模板
        :return: HTML格式的预览内容
        """
        doc = Document(file_path)
        html_content = "<html><body>"

        # 只预览前20段以避免性能问题
        preview_paragraphs = doc.paragraphs[:20]

        for para in preview_paragraphs:
            style_name = para.style.name.lower()
            style_type = "body"

            if "title" in style_name:
                style_type = "title"
            elif "heading 1" in style_name:
                style_type = "heading1"
            elif "heading 2" in style_name:
                style_type = "heading2"

            style = template.get(style_type, {})
            html_content += self._para_to_html(para, style)

        html_content += "</body></html>"
        return html_content

    def _format_paragraph(self, paragraph, style: Dict):
        """格式化单个段落"""
        # 获取字号并转换为磅值
        font_size = self.convert_font_size(style.get("size", 12))
        # 获取字号
        size_str = str(style.get("size", "12"))
        chinese_sizes = {
            "初号": 42, "小初": 36, "一号": 26, "小一": 24,
            "二号": 22, "小二": 18, "三号": 16, "小三": 15,
            "四号": 14, "小四": 12, "五号": 10.5, "小五": 9,
            "六号": 7.5, "小六": 6.5, "七号": 5.5, "八号": 5
        }

        # 如果是中文标准字号
        if size_str in chinese_sizes:
            font_size = Pt(chinese_sizes[size_str])
        else:
            # 尝试转换为数字
            try:
                font_size = Pt(float(size_str))
            except ValueError:
                font_size = Pt(12)  # 默认值

        # 应用字号
        font = paragraph.style.font
        font.size = font_size
        # 设置字体
#        font = paragraph.style.font
        font.name = style.get("font", "宋体")
#        font.size = Pt(style.get("size", 12))
        font.bold = style.get("bold", False)
        font.italic = style.get("italic", False)

        # 设置颜色
        color = style.get("color", "黑色")
        font.color.rgb = self.color_map.get(color, RGBColor(0, 0, 0))

        # 设置对齐方式
        align_map = {
            "left": WD_PARAGRAPH_ALIGNMENT.LEFT,
            "center": WD_PARAGRAPH_ALIGNMENT.CENTER,
            "right": WD_PARAGRAPH_ALIGNMENT.RIGHT,
            "justify": WD_PARAGRAPH_ALIGNMENT.JUSTIFY
        }
        paragraph.alignment = align_map.get(style.get("alignment", "left"),
                                         WD_PARAGRAPH_ALIGNMENT.LEFT)

        # 设置段落格式
        paragraph_format = paragraph.paragraph_format

        # 首行缩进 (转换为磅，1厘米≈28.35磅)
        indent = style.get("first_line_indent", 0)
        paragraph_format.first_line_indent = Pt(indent)  # 直接使用传入的磅值

        # 行间距 (1磅=1/72英寸)
        line_spacing = style.get("line_spacing", 1.5)
        paragraph_format.line_spacing = line_spacing

        # 段间距
        space_before = style.get("space_before", 0)
        space_after = style.get("space_after", 0)
        paragraph_format.space_before = Pt(space_before)
        paragraph_format.space_after = Pt(space_after)

    def _format_paragraphs(self, paragraphs, style: Dict, is_title: bool = False):
        """格式化多个段落"""
        for para in paragraphs:
            if is_title and para.text.strip():
                self._format_paragraph(para, style)
                break  # 通常只有一个标题



    def _para_to_html(self, paragraph, style: Dict) -> str:
        """将段落转换为HTML"""
        text = paragraph.text

        if not text.strip():
            return "<p><br/></p>"

        # 应用样式
        font = style.get("font", "宋体")
        size = style.get("size", 12)
        bold = "font-weight:bold;" if style.get("bold", False) else ""
        italic = "font-style:italic;" if style.get("italic", False) else ""
        color = style.get("color", "黑色")

        align_map = {
            "left": "left",
            "center": "center",
            "right": "right",
            "justify": "justify"
        }
        align = align_map.get(style.get("alignment", "left"), "left")

        indent = style.get("first_line_indent", 0)
        line_spacing = style.get("line_spacing", 1.5)

        html = f"""
        <p style="
            font-family:'{font}';
            font-size:{size}pt;
            {bold}
            {italic}
            color:{color};
            text-align:{align};
            text-indent:{indent}pt;
            line-height:{line_spacing};
            margin-top:{style.get('space_before', 0)}pt;
            margin-bottom:{style.get('space_after', 0)}pt;
        ">
            {text}
        </p>
        """
        return html

    def convert_font_size(self, size):
        """
        将各种格式的字号统一转换为磅值
        支持:
        - 中文标准字号(如"二号"、"小四")
        - 数字字符串(如"12")
        - 数字(如12)
        """
        if size is None:
            return 12  # 默认值

        # 中文标准字号映射
        chinese_sizes = {
            "初号": 42, "小初": 36, "一号": 26, "小一": 24,
            "二号": 22, "小二": 18, "三号": 16, "小三": 15,
            "四号": 14, "小四": 12, "五号": 10.5, "小五": 9,
            "六号": 7.5, "小六": 6.5, "七号": 5.5, "八号": 5
        }

        # 如果是中文标准字号
        if isinstance(size, str) and size in chinese_sizes:
            return chinese_sizes[size]

        # 尝试转换为数字
        try:
            return float(size)
        except (ValueError, TypeError):
            return 12  # 默认值
